﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BlueLotus7.DBDeploymentTool
{
    internal class SqlExecutor
    {
        public string LoginName
        {
            get;
            private set;
        }

        public string LoginPassword
        {
            get;
            private set;
        }

        public string DBName
        {
            get;
            private set;
        }

        public string Server
        {
            get;
            private set;
        }

        public string ScriptContainer
        {
            get;
            private set;
        }

        public SqlExecutor(string loginName, string loginPassword, string server, string dbName, string scriptContainer)
        {
            this.LoginName = loginName;
            this.LoginPassword = loginPassword;
            this.DBName = dbName;
            this.ScriptContainer = scriptContainer;
            this.Server = server;
        }

        public void Execute()
        {
            if (!string.IsNullOrWhiteSpace(this.LoginName) && !string.IsNullOrWhiteSpace(this.LoginPassword) && !string.IsNullOrWhiteSpace(this.DBName) && !string.IsNullOrWhiteSpace(this.ScriptContainer))
            {
                if (string.IsNullOrWhiteSpace(this.Server))
                {
                    this.Server = "localhost";
                }
                DirectoryInfo container = null;

                try
                {
                    container = new DirectoryInfo(this.ScriptContainer);
                    if (container.Exists)
                    {
                        ExecuteAllFiles(container.GetDirectories("Table", SearchOption.TopDirectoryOnly));
                        ExecuteAllFiles(container.GetDirectories("Function", SearchOption.TopDirectoryOnly));
                        ExecuteAllFiles(container.GetDirectories("View", SearchOption.TopDirectoryOnly));
                        ExecuteAllFiles(container.GetDirectories("SP", SearchOption.TopDirectoryOnly));
                        ExecuteAllFiles(container.GetDirectories("Data", SearchOption.TopDirectoryOnly));
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(
                        string.Format("Type: {0} \r\n Message: {1} \r\n TraceStack: {2}",
                        ex.GetType().ToString(),
                        ex.Message,
                        ex.StackTrace));
                }
            }
        }

        private void ExecuteAllFiles(DirectoryInfo[] folders)
        {
            if (folders != null && folders.Length > 0)
            {
                foreach (var one in folders)
                {
                    ExecuteAllFiles(one);
                }
            }
        }

        private void ExecuteAllFiles(DirectoryInfo folder)
        {
            foreach (var one in folder.GetFiles("*.sql"))
            {
                string cmd = GenerateSqlCmd(one.FullName);
                try
                {
                    Console.WriteLine("Execute: " + one.FullName);
                    Process process = new Process();
                    process.StartInfo.FileName = "osql.exe";
                    process.StartInfo.Arguments = cmd.Substring(5);
                    process.StartInfo.UseShellExecute = false;
                    process.StartInfo.RedirectStandardOutput = true;  //重定向输出
                    process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;//隐藏输出窗口
                    process.Start();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(
                      string.Format("Error occurred when executing: {2} \r\n Type: {0} \r\n Message: {1}",
                      ex.GetType().ToString(),
                      ex.Message,
                      cmd
                      ));
                }
            }

            foreach (var one in folder.GetDirectories())
            {
                ExecuteAllFiles(one);
            }
        }

        private string GenerateSqlCmd(string filePath)
        {
            const string format = @"osql -S""{0}"" -U""{1}"" -P""{2}"" -d""{3}"" -i""{4}""";
            return string.Format(format, this.Server, this.LoginName, this.LoginPassword, this.DBName, filePath);
        }
    }
}
